﻿using SCM.Common.Attributes;
using System;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.Linq;
using SCM.Common;
using SCM.Model.DBEntity;
using SCM.Servie.Business;
using SCM.Model.Enums;
using SCM.Model;
using Microsoft.Extensions.Configuration;
using System.Security.Principal;
using System.Security.Claims;

namespace SCM.WebAPI.Controllers
{
    /// <summary>
    /// 父控制器
    /// </summary>
    [SCMAuthorize]
    public class BaseController : ControllerBase, IDisposable
    {
        /// <summary>
        /// 添加业务日志
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="requestData"></param>
        /// <param name="content"></param>
        protected void AddBusinessLog<T>(T requestData, string content)
        {
            string json = "";
            if (requestData != null)
            {
                json = JsonConvert.SerializeObject(requestData);
            }
            ILogger<BaseController> logger = GetService<ILogger<BaseController>>();
            var logService = GetService<LogService>();
            var model = new T_BusinessExceptionLog();
            model.ClientIP = GetAddressIPV4();
            model.Content = content;
            model.ProcessFlag = ProcessFlagEnum.WaitHandle;
            model.RequestData = json;
            model.RequestUrl = HttpContext.Request.GetDisplayUrl();
            model.UserName = this.HttpContext?.User?.Identity?.Name;
            logger?.LogError(JsonConvert.SerializeObject(model));
            logService.AddBusinessLog(model);
        }

        /// <summary>
        /// 获取UserAccount
        /// </summary>
        /// <returns></returns>
        protected string GetUserName()
        {
            return this.HttpContext.User?.Identity?.Name;
        }

        /// <summary>
        /// 获取用户ID
        /// </summary>
        /// <returns></returns>
        protected string GetUserId()
        {
            var userNo = HttpContext.User?.Claims.FirstOrDefault(p => p.Type == "UserId");
            if (userNo == null)
            {
                return "";
            }
            return userNo.Value;
        }

        /// <summary>
        /// 通用返回成功结果
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="data"></param>
        /// <returns></returns>
        protected ViewDataPack<T> GetOK<T>(T data)
        {
            return new ViewDataPack<T> { Code = ResultCode.OK, Data = data};
        }

        /// <summary>
        /// 通用返回分页结果
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="data"></param>
        /// <param name="page"></param>
        /// <returns></returns>
        protected ViewDataPagePack<T> GetPageOK<T>(T data, PageInfo page)
        {
            return new ViewDataPagePack<T> { Code = ResultCode.OK, Data = data, PageInfo = page};
        }

        private IServiceScope scope = null;

        /// <summary>
        /// 获取依赖注入服务
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        protected T GetService<T>()
        {
            if (scope == null)
            {
                scope = ServiceLocator.Instance.CreateScope();
            }
            return scope.ServiceProvider.GetRequiredService<T>();
        }

        /// <summary>
        /// 获取IP
        /// </summary>
        /// <returns></returns>
        protected string GetAddressIPV4()
        {
            return base.HttpContext.Connection.RemoteIpAddress.MapToIPv4().ToString();
        }

        /// <summary>
        /// 释放
        /// </summary>
        public void Dispose()
        {
            if (scope != null)
            {
                scope.Dispose();
            }
        }

        /// <summary>
        /// Token登录
        /// </summary>
        /// <param name="user"></param>
        /// <param name="roleIds"></param>
        /// <returns></returns>
        protected string TokenLogin(T_User user, string[] roleIds)
        {
            var redisLogin = new RedisLoginUser();
            redisLogin.CompanyID = user.CompanyID;
            redisLogin.UserID = user.ID;
            redisLogin.Phone = user.Phone;
            redisLogin.Email = user.Email;
            redisLogin.RoleIds = roleIds;
            redisLogin.UserDisplayName = user.UserDisplayName;

            int expire;
            if (!int.TryParse(GetService<IConfiguration>()?.GetSection("TokenExpire").Value, out expire))
            {
                expire = 600;
            }
 
            if (RedisService.GetRedisHelper().Set(user.Phone, JsonConvert.SerializeObject(redisLogin), expire))
            {
                GenericIdentity identity = new GenericIdentity(user.Phone);
                identity.AddClaim(new Claim(ClaimTypes.Name, user.UserDisplayName));
                identity.AddClaim(new Claim("UserId", user.ID));

                GenericPrincipal principal = new GenericPrincipal(identity, roleIds);
                this.HttpContext.User = principal;
                return AccessToken.Encry(new AccessToken { Phone = user.Phone });
            }
            return "";
        }
    }
}
